﻿using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Batman.Cms.Core.Models.Mvc;
using Batman.Jianbei.Forum.Controllers.Users.Filters;
using Batman.Jianbei.Forum.Controllers.Users.Input;
using Batman.Jianbei.Forum.Controllers.Users.Responses;
using Batman.Jianbei.Forum.Core.Datas;
using Batman.Jianbei.Forum.Core.Domains;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Omu.ValueInjecter;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Batman.Jianbei.Forum.Services.Users
{
    public class SuperAdminService : ApplicationService
    {
        JianbeiForumDbContext context;

        public UserManager<User> usermanager { get; set; }

        public SuperAdminService()
        {
            context = new JianbeiForumDbContextFactory().CreateDbContext(null);
        }

        /// <summary>
        /// 批量创建用户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResponseBase> CreateUser(List<UserCreateDto> model)
        {
            foreach (var newUserModel in model)
            {

                var user = await context.Users.AsNoTracking().FirstOrDefaultAsync(t => t.UserName == newUserModel.UserName);
                if (user != null)
                {
                    return new ResponseBase(false, $"用户名已存在:{newUserModel.UserName}");
                }

                var role = await context.Roles.AsNoTracking().FirstOrDefaultAsync(t => t.Id == newUserModel.RoleId);

                if (role == null)
                {
                    return new ResponseBase(false, "所选角色不存在");
                }

                var newUser = new User();
                newUserModel.Password = string.IsNullOrEmpty(newUserModel.Password) ? "my!password@123" : newUserModel.Password;
                newUser.InjectFrom(newUserModel);
                newUser.SetPassword(newUserModel.Password);

                await usermanager.CreateAsync(newUser);

                await context.UserRoles.AddAsync(new IdentityUserRole<string>
                {
                    UserId = newUser.Id,
                    RoleId = newUserModel.RoleId
                });
            }

            await context.SaveChangesAsync();

            return new ResponseBase(true);
        }

        public async Task<PagedResultDto<UserDto>> GetUsers(PagedResultRequestDto page, UserFilter filter)
        {
            var users = context.Users.AsNoTracking();

            if (!string.IsNullOrEmpty(filter.Username))
            {
                users = users.Where(t => t.UserName.Contains(filter.Username));
            }

            var results = await users.OrderByDescending(t => t.CreateAt)
                                     .Skip(page.SkipCount)
                                     .Take(page.MaxResultCount)
                                     .Select(t => new UserDto
                                     {
                                         Id = t.Id,
                                         Username = t.UserName,
                                     }).ToListAsync();

            var userRoles = context.UserRoles.AsNoTracking();

            // Name:用户ID，Value:角色ID
            var userRoleList = await userRoles.Where(t => results.Any(s => s.Id == t.UserId))
                                              .Select(t => new NameValueDto(t.UserId, t.RoleId))
                                              .ToListAsync();

            var roles = context.Roles.AsNoTracking();

            var roleList = await roles.Where(t => userRoleList.Any(s => s.Value == t.Id)).ToListAsync();

            results.ForEach(t =>
            {
                var m = userRoleList.Where(s => s.Name == t.Id).ToList();
                t.Roles = new List<NameValueDto>();

                foreach (var item in m)
                {
                    var role = GetRole(roleList, item.Value);
                    t.Roles.Add(role);
                }
            });

            var total = users.Count();
            return new PagedResultDto<UserDto>(total, results);
        }

        /// <summary>
        /// 从rolesHub中找出id等于roleId的角色信息
        /// </summary>
        /// <param name="rolesHub"></param>
        /// <param name="roleId"></param>
        /// <returns>Name:角色名称 Value:角色ID</returns>
        private NameValueDto GetRole(List<IdentityRole> rolesHub, string roleId)
        {
            return rolesHub.Where(t => t.Id == roleId).Select(t => new NameValueDto(t.Name, t.Id)).FirstOrDefault();
        }
    }
}
